<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

/**
 * Think 标准模式公共函数库
 *
 * @category Think
 * @package Common
 * @author liu21st <liu21st@gmail.com>
 */

/**
 * 错误输出
 *
 * @param mixed $error
 *        	错误
 * @return void
 */
function halt($error) {
	$e = array ();
	if (APP_DEBUG) {
		// 调试模式下输出错误信息
		if (! is_array ( $error )) {
			$trace = debug_backtrace ();
			$e ['message'] = $error;
			$e ['file'] = $trace [0] ['file'];
			$e ['class'] = isset ( $trace [0] ['class'] ) ? $trace [0] ['class'] : '';
			$e ['function'] = isset ( $trace [0] ['function'] ) ? $trace [0] ['function'] : '';
			$e ['line'] = $trace [0] ['line'];
			$traceInfo = '';
			$time = date ( 'y-m-d H:i:m' );
			foreach ( $trace as $t ) {
				$traceInfo .= '[' . $time . '] ' . $t ['file'] . ' (' . $t ['line'] . ') ';
				$traceInfo .= $t ['class'] . $t ['type'] . $t ['function'] . '(';
				$traceInfo .= implode ( ', ', $t ['args'] );
				$traceInfo .= ')<br/>';
			}
			$e ['trace'] = $traceInfo;
		} else {
			$e = $error;
		}
	} else {
		// 否则定向到错误页面
		$error_page = C ( 'ERROR_PAGE' );
		if (! empty ( $error_page )) {
			redirect ( $error_page );
		} else {
			if (C ( 'SHOW_ERROR_MSG' ))
				$e ['message'] = is_array ( $error ) ? $error ['message'] : $error;
			else
				$e ['message'] = C ( 'ERROR_MESSAGE' );
		}
	}
	// 包含异常页面模板
	include C ( 'TMPL_EXCEPTION_FILE' );
	exit ();
}

/**
 * 自定义异常处理
 *
 * @param string $msg
 *        	异常消息
 * @param string $type
 *        	异常类型 默认为ThinkException
 * @param integer $code
 *        	异常代码 默认为0
 * @return void
 */
function throw_exception($msg, $type = 'ThinkException', $code = 0) {
	if (class_exists ( $type, false ))
		throw new $type ( $msg, $code, true );
	else
		halt ( $msg ); // 异常类型不存在则输出错误信息字串
}

/**
 * 浏览器友好的变量输出
 *
 * @param mixed $var
 *        	变量
 * @param boolean $echo
 *        	是否输出 默认为True 如果为false 则返回输出字符串
 * @param string $label
 *        	标签 默认为空
 * @param boolean $strict
 *        	是否严谨 默认为true
 * @return void string
 */
function dump($var, $echo = true, $label = null, $strict = true) {
	$label = ($label === null) ? '' : rtrim ( $label ) . ' ';
	if (! $strict) {
		if (ini_get ( 'html_errors' )) {
			$output = print_r ( $var, true );
			$output = '<pre>' . $label . htmlspecialchars ( $output, ENT_QUOTES ) . '</pre>';
		} else {
			$output = $label . print_r ( $var, true );
		}
	} else {
		ob_start ();
		var_dump ( $var );
		$output = ob_get_clean ();
		if (! extension_loaded ( 'xdebug' )) {
			$output = preg_replace ( "/\]\=\>\n(\s+)/m", '] => ', $output );
			$output = '<pre>' . $label . htmlspecialchars ( $output, ENT_QUOTES ) . '</pre>';
		}
	}
	if ($echo) {
		echo ($output);
		return null;
	} else
		return $output;
}

/**
 * 404处理
 * 调试模式会抛异常
 * 部署模式下面传入url参数可以指定跳转页面，否则发送404信息
 *
 * @param string $msg
 *        	提示信息
 * @param string $url
 *        	跳转URL地址
 * @return void
 */
function _404($msg = '', $url = '') {
	APP_DEBUG && throw_exception ( $msg );
	if ($msg && C ( 'LOG_EXCEPTION_RECORD' ))
		Log::write ( $msg );
	if (empty ( $url ) && C ( 'URL_404_REDIRECT' )) {
		$url = C ( 'URL_404_REDIRECT' );
	}
	if ($url) {
		redirect ( $url );
	} else {
		send_http_status ( 404 );
		exit ();
	}
}

/**
 * 设置当前页面的布局
 *
 * @param string|false $layout
 *        	布局名称 为false的时候表示关闭布局
 * @return void
 */
function layout($layout) {
	if (false !== $layout) {
		// 开启布局
		C ( 'LAYOUT_ON', true );
		if (is_string ( $layout )) { // 设置新的布局模板
			C ( 'LAYOUT_NAME', $layout );
		}
	} else { // 临时关闭布局
		C ( 'LAYOUT_ON', false );
	}
}

/**
 * URL组装 支持不同URL模式
 *
 * @param string $url
 *        	URL表达式，格式：'[分组/模块/操作@域名]?参数1=值1&参数2=值2...'
 * @param string|array $vars
 *        	传入的参数，支持数组和字符串
 * @param string $suffix
 *        	伪静态后缀，默认为true表示获取配置值
 * @param boolean $redirect
 *        	是否跳转，如果设置为true则表示跳转到该URL地址
 * @param boolean $domain
 *        	是否显示域名
 * @return string
 */
function U($url = '', $vars = '', $suffix = true, $redirect = false, $domain = false) {
	// 解析URL
	$info = parse_url ( $url );
	$url = ! empty ( $info ['path'] ) ? $info ['path'] : ACTION_NAME;
	if (false !== strpos ( $url, '@' )) { // 解析域名
		list ( $url, $host ) = explode ( '@', $info ['path'], 2 );
	}
	// 解析子域名
	if (isset ( $host )) {
		$domain = $host . (strpos ( $host, '.' ) ? '' : strstr ( $_SERVER ['HTTP_HOST'], '.' ));
	} elseif ($domain === true) {
		$domain = $_SERVER ['HTTP_HOST'];
		if (C ( 'APP_SUB_DOMAIN_DEPLOY' )) { // 开启子域名部署
			$domain = $domain == 'localhost' ? 'localhost' : 'www' . strstr ( $_SERVER ['HTTP_HOST'], '.' );
			// '子域名'=>array('项目[/分组]');
			foreach ( C ( 'APP_SUB_DOMAIN_RULES' ) as $key => $rule ) {
				if (false === strpos ( $key, '*' ) && 0 === strpos ( $url, $rule [0] )) {
					$domain = $key . strstr ( $domain, '.' ); // 生成对应子域名
					$url = substr_replace ( $url, '', 0, strlen ( $rule [0] ) );
					break;
				}
			}
		}
	}
	
	// 解析参数
	if (is_string ( $vars )) { // aaa=1&bbb=2 转换成数组
		parse_str ( $vars, $vars );
	} elseif (! is_array ( $vars )) {
		$vars = array ();
	}
	if (isset ( $info ['query'] )) { // 解析地址里面参数 合并到vars
		parse_str ( $info ['query'], $params );
		$vars = array_merge ( $params, $vars );
	}
	
	// URL组装
	$depr = C ( 'URL_PATHINFO_DEPR' );
	if ($url) {
		if (0 === strpos ( $url, '/' )) { // 定义路由
			$route = true;
			$url = substr ( $url, 1 );
			if ('/' != $depr) {
				$url = str_replace ( '/', $depr, $url );
			}
		} else {
			if ('/' != $depr) { // 安全替换
				$url = str_replace ( '/', $depr, $url );
			}
			// 解析分组、模块和操作
			$url = trim ( $url, $depr );
			$path = explode ( $depr, $url );
			$var = array ();
			$var [C ( 'VAR_ACTION' )] = ! empty ( $path ) ? array_pop ( $path ) : ACTION_NAME;
			$var [C ( 'VAR_MODULE' )] = ! empty ( $path ) ? array_pop ( $path ) : MODULE_NAME;
			if (C ( 'URL_CASE_INSENSITIVE' )) {
				$var [C ( 'VAR_MODULE' )] = parse_name ( $var [C ( 'VAR_MODULE' )] );
			}
			if (! C ( 'APP_SUB_DOMAIN_DEPLOY' ) && C ( 'APP_GROUP_LIST' )) {
				if (! empty ( $path )) {
					$group = array_pop ( $path );
					$var [C ( 'VAR_GROUP' )] = $group;
				} else {
					if (GROUP_NAME != C ( 'DEFAULT_GROUP' )) {
						$var [C ( 'VAR_GROUP' )] = GROUP_NAME;
					}
				}
				if (C ( 'URL_CASE_INSENSITIVE' ) && isset ( $var [C ( 'VAR_GROUP' )] )) {
					$var [C ( 'VAR_GROUP' )] = strtolower ( $var [C ( 'VAR_GROUP' )] );
				}
			}
		}
	}
	
	if (C ( 'URL_MODEL' ) == 0) { // 普通模式URL转换
		$url = __APP__ . '?' . http_build_query ( array_reverse ( $var ) );
		if (! empty ( $vars )) {
			$vars = urldecode ( http_build_query ( $vars ) );
			$url .= '&' . $vars;
		}
	} else { // PATHINFO模式或者兼容URL模式
		if (isset ( $route )) {
			$url = __APP__ . '/' . rtrim ( $url, $depr );
		} else {
			$url = __APP__ . '/' . implode ( $depr, array_reverse ( $var ) );
		}
		if (! empty ( $vars )) { // 添加参数
			foreach ( $vars as $var => $val )
				$url .= $depr . $var . $depr . $val;
		}
		if ($suffix) {
			$suffix = $suffix === true ? C ( 'URL_HTML_SUFFIX' ) : $suffix;
			if ($pos = strpos ( $suffix, '|' )) {
				$suffix = substr ( $suffix, 0, $pos );
			}
			if ($suffix && $url [1]) {
				$url .= '.' . ltrim ( $suffix, '.' );
			}
		}
	}
	if ($domain) {
		$url = (is_ssl () ? 'https://' : 'http://') . $domain . $url;
	}
	if ($redirect) // 直接跳转URL
		redirect ( $url );
	else
		return $url;
}

/**
 * 判断是否SSL协议
 *
 * @return boolean
 */
function is_ssl() {
	if (isset ( $_SERVER ['HTTPS'] ) && ('1' == $_SERVER ['HTTPS'] || 'on' == strtolower ( $_SERVER ['HTTPS'] ))) {
		return true;
	} elseif (isset ( $_SERVER ['SERVER_PORT'] ) && ('443' == $_SERVER ['SERVER_PORT'])) {
		return true;
	}
	return false;
}

/**
 * URL重定向
 *
 * @param string $url
 *        	重定向的URL地址
 * @param integer $time
 *        	重定向的等待时间（秒）
 * @param string $msg
 *        	重定向前的提示信息
 * @return void
 */
function redirect($url, $time = 0, $msg = '') {
	// 多行URL地址支持
	$url = str_replace ( array (
			"\n",
			"\r" 
	), '', $url );
	if (empty ( $msg ))
		$msg = "系统将在{$time}秒之后自动跳转到{$url}！";
	if (! headers_sent ()) {
		// redirect
		if (0 === $time) {
			header ( 'Location: ' . $url );
		} else {
			header ( "refresh:{$time};url={$url}" );
			echo ($msg);
		}
		exit ();
	} else {
		$str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
		if ($time != 0)
			$str .= $msg;
		exit ( $str );
	}
}

/**
 * 缓存管理
 *
 * @param string|array $name
 *        	缓存名称，如果为数组表示进行缓存设置
 * @param mixed $value
 *        	缓存值
 * @param integer $expire
 *        	缓存有效期（秒）
 * @return mixed
 */
function cache($name, $value = '', $expire = 0) {
	static $cache = '';
	if (is_array ( $name )) { // 缓存初始化
		$type = isset ( $name ['type'] ) ? $name ['type'] : C ( 'DATA_CACHE_TYPE' );
		unset ( $name ['type'] );
		$cache = Cache::getInstance ( $type, $name );
		return $cache;
	}
	if (empty ( $cache )) { // 自动初始化
		$cache = Cache::getInstance ();
	}
	if ('' === $value) { // 获取缓存值
	                     // 获取缓存数据
		return $cache->get ( $name );
	} elseif (is_null ( $value )) { // 删除缓存
		return $cache->rm ( $name );
	} else { // 缓存数据
		return $cache->set ( $name, $value, $expire );
	}
}

/**
 * 全局缓存设置和读取
 *
 * @param string $name
 *        	缓存名称
 * @param mixed $value
 *        	缓存值
 * @param integer $expire
 *        	缓存有效期（秒）
 * @param string $type
 *        	缓存类型
 * @param array $options
 *        	缓存参数
 * @return mixed
 */
function S($name, $value = '', $expire = null, $type = '', $options = null) {
	static $_cache = array ();
	// 取得缓存对象实例
	$cache = Cache::getInstance ( $type, $options );
	if ('' !== $value) {
		if (is_null ( $value )) {
			// 删除缓存
			$result = $cache->rm ( $name );
			if ($result)
				unset ( $_cache [$type . '_' . $name] );
			return $result;
		} else {
			// 缓存数据
			$cache->set ( $name, $value, $expire );
			$_cache [$type . '_' . $name] = $value;
		}
		return;
	}
	if (isset ( $_cache [$type . '_' . $name] ))
		return $_cache [$type . '_' . $name];
		// 获取缓存数据
	$value = $cache->get ( $name );
	$_cache [$type . '_' . $name] = $value;
	return $value;
}

/**
 * 快速文件数据读取和保存 针对简单类型数据 字符串、数组
 *
 * @param string $name
 *        	缓存名称
 * @param mixed $value
 *        	缓存值
 * @param string $path
 *        	缓存路径
 * @return mixed
 */
function F($name, $value = '', $path = DATA_PATH) {
	static $_cache = array ();
	$filename = $path . $name . '.php';
	if ('' !== $value) {
		if (is_null ( $value )) {
			// 删除缓存
			return unlink ( $filename );
		} else {
			// 缓存数据
			$dir = dirname ( $filename );
			// 目录不存在则创建
			if (! is_dir ( $dir ))
				mkdir ( $dir, 0777, true );
			$_cache [$name] = $value;
			return file_put_contents ( $filename, json_encode ( $value ) );
		}
	}
	if (isset ( $_cache [$name] ))
		return $_cache [$name];
		// 获取缓存数据
	if (is_file ( $filename )) {
		$value = json_decode ( file_get_contents ( $filename ), true );
		$_cache [$name] = $value;
	} else {
		$value = false;
	}
	return $value;
}

/**
 * 取得对象实例 支持调用类的静态方法
 *
 * @param string $name
 *        	类名
 * @param string $method
 *        	方法名，如果为空则返回实例化对象
 * @param array $args
 *        	调用参数
 * @return object
 */
function get_instance_of($name, $method = '', $args = array()) {
	static $_instance = array ();
	$identify = empty ( $args ) ? $name . $method : $name . $method . to_guid_string ( $args );
	if (! isset ( $_instance [$identify] )) {
		if (class_exists ( $name )) {
			$o = new $name ();
			if (method_exists ( $o, $method )) {
				if (! empty ( $args )) {
					$_instance [$identify] = call_user_func_array ( array (
							&$o,
							$method 
					), $args );
				} else {
					$_instance [$identify] = $o->$method ();
				}
			} else
				$_instance [$identify] = $o;
		} else
			halt ( L ( '_CLASS_NOT_EXIST_' ) . ':' . $name );
	}
	return $_instance [$identify];
}

/**
 * 根据PHP各种类型变量生成唯一标识号
 *
 * @param mixed $mix
 *        	变量
 * @return string
 */
function to_guid_string($mix) {
	if (is_object ( $mix ) && function_exists ( 'spl_object_hash' )) {
		return spl_object_hash ( $mix );
	} elseif (is_resource ( $mix )) {
		$mix = get_resource_type ( $mix ) . strval ( $mix );
	} else {
		$mix = serialize ( $mix );
	}
	return md5 ( $mix );
}

/**
 * XML编码
 *
 * @param mixed $data
 *        	数据
 * @param string $encoding
 *        	数据编码
 * @param string $root
 *        	根节点名
 * @return string
 */
function xml_encode($data, $encoding = 'utf-8', $root = 'think') {
	$xml = '<?xml version="1.0" encoding="' . $encoding . '"?>';
	$xml .= '<' . $root . '>';
	$xml .= data_to_xml ( $data );
	$xml .= '</' . $root . '>';
	return $xml;
}

/**
 * 数据XML编码
 *
 * @param mixed $data
 *        	数据
 * @return string
 */
function data_to_xml($data) {
	$xml = '';
	foreach ( $data as $key => $val ) {
		is_numeric ( $key ) && $key = "item id=\"$key\"";
		$xml .= "<$key>";
		$xml .= (is_array ( $val ) || is_object ( $val )) ? data_to_xml ( $val ) : $val;
		list ( $key, ) = explode ( ' ', $key );
		$xml .= "</$key>";
	}
	return $xml;
}

/**
 * session管理函数
 *
 * @param string|array $name
 *        	session名称 如果为数组则表示进行session设置
 * @param mixed $value
 *        	session值
 * @return mixed
 */
function session($name, $value = '') {
	$prefix = C ( 'SESSION_PREFIX' );
	if (is_array ( $name )) { // session初始化 在session_start 之前调用
		if (isset ( $name ['prefix'] ))
			C ( 'SESSION_PREFIX', $name ['prefix'] );
		if (C ( 'VAR_SESSION_ID' ) && isset ( $_REQUEST [C ( 'VAR_SESSION_ID' )] )) {
			session_id ( $_REQUEST [C ( 'VAR_SESSION_ID' )] );
		} elseif (isset ( $name ['id'] )) {
			session_id ( $name ['id'] );
		}
		ini_set ( 'session.auto_start', 0 );
		if (isset ( $name ['name'] ))
			session_name ( $name ['name'] );
		if (isset ( $name ['path'] ))
			session_save_path ( $name ['path'] );
		if (isset ( $name ['domain'] ))
			ini_set ( 'session.cookie_domain', $name ['domain'] );
		if (isset ( $name ['expire'] ))
			ini_set ( 'session.gc_maxlifetime', $name ['expire'] );
		if (isset ( $name ['use_trans_sid'] ))
			ini_set ( 'session.use_trans_sid', $name ['use_trans_sid'] ? 1 : 0 );
		if (isset ( $name ['use_cookies'] ))
			ini_set ( 'session.use_cookies', $name ['use_cookies'] ? 1 : 0 );
		if (isset ( $name ['cache_limiter'] ))
			session_cache_limiter ( $name ['cache_limiter'] );
		if (isset ( $name ['cache_expire'] ))
			session_cache_expire ( $name ['cache_expire'] );
		if (isset ( $name ['type'] ))
			C ( 'SESSION_TYPE', $name ['type'] );
		if (C ( 'SESSION_TYPE' )) { // 读取session驱动
			$class = 'Session' . ucwords ( strtolower ( C ( 'SESSION_TYPE' ) ) );
			// 检查驱动类
			if (require_cache ( EXTEND_PATH . 'Driver/Session/' . $class . '.class.php' )) {
				$hander = new $class ();
				$hander->execute ();
			} else {
				// 类没有定义
				throw_exception ( L ( '_CLASS_NOT_EXIST_' ) . ': ' . $class );
			}
		}
		// 启动session
		if (C ( 'SESSION_AUTO_START' ))
			session_start ();
	} elseif ('' === $value) {
		if (0 === strpos ( $name, '[' )) { // session 操作
			if ('[pause]' == $name) { // 暂停session
				session_write_close ();
			} elseif ('[start]' == $name) { // 启动session
				session_start ();
			} elseif ('[destroy]' == $name) { // 销毁session
				$_SESSION = array ();
				session_unset ();
				session_destroy ();
			} elseif ('[regenerate]' == $name) { // 重新生成id
				session_regenerate_id ();
			}
		} elseif (0 === strpos ( $name, '?' )) { // 检查session
			$name = substr ( $name, 1 );
			if ($prefix) {
				return isset ( $_SESSION [$prefix] [$name] );
			} else {
				return isset ( $_SESSION [$name] );
			}
		} elseif (is_null ( $name )) { // 清空session
			if ($prefix) {
				unset ( $_SESSION [$prefix] );
			} else {
				$_SESSION = array ();
			}
		} elseif ($prefix) { // 获取session
			return isset ( $_SESSION [$prefix] [$name] ) ? $_SESSION [$prefix] [$name] : null;
		} else {
			return isset ( $_SESSION [$name] ) ? $_SESSION [$name] : null;
		}
	} elseif (is_null ( $value )) { // 删除session
		if ($prefix) {
			unset ( $_SESSION [$prefix] [$name] );
		} else {
			unset ( $_SESSION [$name] );
		}
	} else { // 设置session
		if ($prefix) {
			if (! is_array ( $_SESSION [$prefix] )) {
				$_SESSION [$prefix] = array ();
			}
			$_SESSION [$prefix] [$name] = $value;
		} else {
			$_SESSION [$name] = $value;
		}
	}
}

/**
 * Cookie 设置、获取、删除
 *
 * @param string $name
 *        	cookie名称
 * @param mixed $value
 *        	cookie值
 * @param mixed $options
 *        	cookie参数
 * @return mixed
 */
function cookie($name, $value = '', $option = null) {
	// 默认设置
	$config = array (
			'prefix' => C ( 'COOKIE_PREFIX' ), // cookie 名称前缀
			'expire' => C ( 'COOKIE_EXPIRE' ), // cookie 保存时间
			'path' => C ( 'COOKIE_PATH' ), // cookie 保存路径
			'domain' => C ( 'COOKIE_DOMAIN' )  // cookie 有效域名
			);
	// 参数设置(会覆盖黙认设置)
	if (! empty ( $option )) {
		if (is_numeric ( $option ))
			$option = array (
					'expire' => $option 
			);
		elseif (is_string ( $option ))
			parse_str ( $option, $option );
		$config = array_merge ( $config, array_change_key_case ( $option ) );
	}
	// 清除指定前缀的所有cookie
	if (is_null ( $name )) {
		if (empty ( $_COOKIE ))
			return;
			// 要删除的cookie前缀，不指定则删除config设置的指定前缀
		$prefix = empty ( $value ) ? $config ['prefix'] : $value;
		if (! empty ( $prefix )) { // 如果前缀为空字符串将不作处理直接返回
			foreach ( $_COOKIE as $key => $val ) {
				if (0 === stripos ( $key, $prefix )) {
					setcookie ( $key, '', time () - 3600, $config ['path'], $config ['domain'] );
					unset ( $_COOKIE [$key] );
				}
			}
		}
		return;
	}
	$name = $config ['prefix'] . $name;
	if ('' === $value) {
		return isset ( $_COOKIE [$name] ) ? json_decode ( MAGIC_QUOTES_GPC ? stripslashes ( $_COOKIE [$name] ) : $_COOKIE [$name] ) : null; // 获取指定Cookie
	} else {
		if (is_null ( $value )) {
			setcookie ( $name, '', time () - 3600, $config ['path'], $config ['domain'] );
			unset ( $_COOKIE [$name] ); // 删除指定cookie
		} else {
			// 设置cookie
			$value = json_encode ( $value );
			$expire = ! empty ( $config ['expire'] ) ? time () + intval ( $config ['expire'] ) : 0;
			setcookie ( $name, $value, $expire, $config ['path'], $config ['domain'] );
			$_COOKIE [$name] = $value;
		}
	}
}

/**
 * 加载动态扩展文件
 *
 * @return void
 */
function load_ext_file() {
	// 加载自定义外部文件
	if (C ( 'LOAD_EXT_FILE' )) {
		$files = explode ( ',', C ( 'LOAD_EXT_FILE' ) );
		foreach ( $files as $file ) {
			$file = COMMON_PATH . $file . '.php';
			if (is_file ( $file ))
				include $file;
		}
	}
	// 加载自定义的动态配置文件
	if (C ( 'LOAD_EXT_CONFIG' )) {
		$configs = C ( 'LOAD_EXT_CONFIG' );
		if (is_string ( $configs ))
			$configs = explode ( ',', $configs );
		foreach ( $configs as $key => $config ) {
			$file = CONF_PATH . $config . '.php';
			if (is_file ( $file )) {
				is_numeric ( $key ) ? C ( include $file ) : C ( $key, include $file );
			}
		}
	}
}

/**
 * 获取客户端IP地址
 *
 * @param integer $type
 *        	返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @return mixed
 */
function get_client_ip($type = 0) {
	$type = $type ? 1 : 0;
	static $ip = NULL;
	if ($ip !== NULL)
		return $ip [$type];
	if (isset ( $_SERVER ['HTTP_X_FORWARDED_FOR'] )) {
		$arr = explode ( ',', $_SERVER ['HTTP_X_FORWARDED_FOR'] );
		$pos = array_search ( 'unknown', $arr );
		if (false !== $pos)
			unset ( $arr [$pos] );
		$ip = trim ( $arr [0] );
	} elseif (isset ( $_SERVER ['HTTP_CLIENT_IP'] )) {
		$ip = $_SERVER ['HTTP_CLIENT_IP'];
	} elseif (isset ( $_SERVER ['REMOTE_ADDR'] )) {
		$ip = $_SERVER ['REMOTE_ADDR'];
	}
	// IP地址合法验证
	$long = ip2long ( $ip );
	$ip = $long ? array (
			$ip,
			$long 
	) : array (
			'0.0.0.0',
			0 
	);
	return $ip [$type];
}

/**
 * 发送HTTP状态
 *
 * @param integer $code
 *        	状态码
 * @return void
 */
function send_http_status($code) {
	static $_status = array (
			// Success 2xx
			200 => 'OK',
			// Redirection 3xx
			301 => 'Moved Permanently',
			302 => 'Moved Temporarily ', // 1.1
			                             // Client Error 4xx
			400 => 'Bad Request',
			403 => 'Forbidden',
			404 => 'Not Found',
			// Server Error 5xx
			500 => 'Internal Server Error',
			503 => 'Service Unavailable' 
	);
	if (isset ( $_status [$code] )) {
		header ( 'HTTP/1.1 ' . $code . ' ' . $_status [$code] );
		// 确保FastCGI模式下正常
		header ( 'Status:' . $code . ' ' . $_status [$code] );
	}
}
// 输出纯文本
function t($text, $parseBr = false) {
	$text = h ( $text, 'text' );
	if (! $parseBr) {
		$text = str_ireplace ( array (
				"\r",
				"\n",
				"\t",
				"&nbsp;" 
		), '', $text );
		$text = htmlspecialchars ( $text, ENT_QUOTES );
	} else {
		$text = htmlspecialchars ( $text, ENT_QUOTES );
		$text = nl2br ( $text );
	}
	$text = trim ( $text );
	return $text;
}
/**
 * 过滤得到安全的html
 * 
 * @param string $text
 *        	待过滤的字符串
 * @param string $type
 *        	默认为string,可选项:INT,FLOAT,BOOL,WORD,ALNUM,CMD,BASE64,ARRAY,PATH,USERNAME
 * @param bool $tagsMethod
 *        	true为开启黑名单，白名单失效。false为开启白名单，黑名单失效.
 * @param bool $attrMethod
 *        	同上
 * @param array $tags
 *        	标签的过滤白名单
 * @param array $attr
 *        	属性名的过滤白名单
 * @param array $tagsBlack
 *        	标签的过滤黑名单
 * @param array $attrBlack
 *        	标签中属性的过滤黑名单
 */
function h($text, $type = 'html', $tagsMethod = true, $attrMethod = true, $xssAuto = 1, $tags = array(), $attr = array(), $tagsBlack = array(), $attrBlack = array()) {
	
	// 无标签格式
	$text_tags = '';
	
	// 只存在字体样式
	$font_tags = '<i><b><u><s><em><strong><font><big><small><sup><sub><bdo><h1><h2><h3><h4><h5><h6>';
	
	// 标题摘要基本格式
	$base_tags = $font_tags . '<p><br><hr><a><img><map><area><pre><code><q><blockquote><acronym><cite><ins><del><center><strike>';
	
	// 兼容Form格式
	$form_tags = $base_tags . '<form><input><textarea><button><select><optgroup><option><label><fieldset><legend>';
	
	// 内容等允许HTML的格式
	$html_tags = $base_tags . '<ul><ol><li><dl><dd><dt><table><caption><td><th><tr><thead><tbody><tfoot><col><colgroup><div><span><object><embed>';
	
	// 专题等全HTML格式
	$all_tags = $form_tags . $html_tags . '<!DOCTYPE><html><head><title><body><base><basefont><script><noscript><applet><object><param><style><frame><frameset><noframes><iframe>';
	
	// 过滤标签
	$text = strip_tags ( $text, ${$type . '_tags'} );
	
	// 过滤攻击代码
	if ($type != 'all') {
		// 过滤危险的属性，如：过滤on事件lang js
		while ( preg_match ( '/(<[^><]+) (lang|onclick|onload|unload|onmouseover|onmouseup|onmouseout|onmousedown|onkeydown|onkeypress|onkeyup|onblur|onchange|onfocus|action|background|codebase|dynsrc|lowsrc)[^><]+/i', $text, $mat ) ) {
			$text = str_ireplace ( $mat [0], $mat [1], $text );
		}
		while ( preg_match ( '/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i', $text, $mat ) ) {
			$text = str_ireplace ( $mat [0], $mat [1] . $mat [3], $text );
		}
	}
	return $text;
}
// 加密函数
function jiami($txt, $key) {
	if (empty ( $key ))
		$key = C ( 'SECURE_CODE' );
	$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=+";
	$nh = rand ( 0, 64 );
	$ch = $chars [$nh];
	$mdKey = md5 ( $key . $ch );
	$mdKey = substr ( $mdKey, $nh % 8, $nh % 8 + 7 );
	$txt = base64_encode ( $txt );
	$tmp = '';
	$i = 0;
	$j = 0;
	$k = 0;
	for($i = 0; $i < strlen ( $txt ); $i ++) {
		$k = $k == strlen ( $mdKey ) ? 0 : $k;
		$j = ($nh + strpos ( $chars, $txt [$i] ) + ord ( $mdKey [$k ++] )) % 64;
		$tmp .= $chars [$j];
	}
	return $ch . $tmp;
}
// 解密函数
function jiemi($txt, $key) {
	if (empty ( $key ))
		$key = C ( 'SECURE_CODE' );
	$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-=+";
	$ch = $txt [0];
	$nh = strpos ( $chars, $ch );
	$mdKey = md5 ( $key . $ch );
	$mdKey = substr ( $mdKey, $nh % 8, $nh % 8 + 7 );
	$txt = substr ( $txt, 1 );
	$tmp = '';
	$i = 0;
	$j = 0;
	$k = 0;
	for($i = 0; $i < strlen ( $txt ); $i ++) {
		$k = $k == strlen ( $mdKey ) ? 0 : $k;
		$j = strpos ( $chars, $txt [$i] ) - $nh - ord ( $mdKey [$k ++] );
		while ( $j < 0 )
			$j += 64;
		$tmp .= $chars [$j];
	}
	return base64_decode ( $tmp );
}
// 友好时间显示
function friendlyDate($sTime, $type = 'normal', $alt = 'false') {
	// sTime=源时间，cTime=当前时间，dTime=时间差
	$cTime = time ();
	$dTime = $cTime - $sTime;
	$dDay = intval ( date ( "Ymd", $cTime ) ) - intval ( date ( "Ymd", $sTime ) );
	$dYear = intval ( date ( "Y", $cTime ) ) - intval ( date ( "Y", $sTime ) );
	// normal：n秒前，n分钟前，n小时前，日期
	if ($type == 'normal') {
		if ($dTime < 60) {
			return $dTime . "秒前";
		} elseif ($dTime < 3600) {
			return intval ( $dTime / 60 ) . "分钟前";
		} elseif ($dTime >= 3600 && $dDay == 0) {
			return intval ( $dTime / 3600 ) . "小时前";
		} elseif ($dYear == 0) {
			return date ( "Y-m-d H:i", $sTime );
		} else {
			return date ( "Y-m-d H:i", $sTime );
		}
	} elseif ($type == 'mohu') {
		if ($dTime < 60) {
			return $dTime . "秒前";
		} elseif ($dTime < 3600) {
			return intval ( $dTime / 60 ) . "分钟前";
		} elseif ($dTime >= 3600 && $dDay == 0) {
			return intval ( $dTime / 3600 ) . "小时前";
		} elseif ($dDay > 0 && $dDay < 3) {
			return intval ( $dDay ) . "天前";
		} elseif ($dDay >= 3) {
			return "3天前";
		} elseif ($dDay >= 30) {
			return "1个月前";
		}
		// full: Y-m-d , H:i:s
	} elseif ($type == 'full') {
		return date ( "Y-m-d , H:i:s", $sTime );
	} elseif ($type == 'ymd') {
		return date ( "Y-m-d", $sTime );
	} else {
		if ($dTime < 60) {
			return $dTime . "秒前";
		} elseif ($dTime < 3600) {
			return intval ( $dTime / 60 ) . "分钟前";
		} elseif ($dTime >= 3600 && $dDay == 0) {
			return intval ( $dTime / 3600 ) . "小时前";
		} elseif ($dYear == 0) {
			return date ( "Y-m-d H:i", $sTime );
		} else {
			return date ( "Y-m-d H:i", $sTime );
		}
	}
}
/**
 * 去一个二维数组中的每个数组的固定的键知道的值来形成一个新的一维数组
 * 
 * @param $pArray 一个二维数组        	
 * @param $pKey 数组的键的名称        	
 * @return 返回新的一维数组
 */
function getSubByKey($pArray, $pKey = "", $pCondition = "") {
	$result = array ();
	foreach ( $pArray as $temp_array ) {
		if (is_object ( $temp_array )) {
			$temp_array = ( array ) $temp_array;
		}
		if (("" != $pCondition && $temp_array [$pCondition [0]] == $pCondition [1]) || "" == $pCondition) {
			$result [] = ("" == $pKey) ? $temp_array : isset ( $temp_array [$pKey] ) ? $temp_array [$pKey] : "";
		}
	}
	return $result;
}
function getShort($str, $length = 40) {
	$str = htmlspecialchars ( $str );
	$str = strip_tags ( $str );
	$str = htmlspecialchars_decode ( $str );
	$strlenth = 0;
	$out = '';
	preg_match_all ( "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/", $str, $match );
	foreach ( $match [0] as $v ) {
		preg_match ( "/[\xe0-\xef][\x80-\xbf]{2}/", $v, $matchs );
		if (! empty ( $matchs [0] )) {
			$strlenth += 1;
		} elseif (is_numeric ( $v )) {
			$strlenth += 0.545;
		} else {
			$strlenth += 0.475;
		}
		
		if ($strlenth > $length) {
			break;
		}
		
		$output .= $v;
	}
	return $output;
}
function showImg($id, $type = '') {
	$map ['id'] = $id;
	$info = M ( 'x_attach' )->where ( $map )->field ( 'savepath,savename' )->find ();
	
	return SITE_URL . $info ['savepath'] . $type . $info ['savename'];
}
// 短网址服务
function getShortURL($longURL) {
	//如果还在开发模式，不需要短网址服务
	if(DEVELOPMENT_MODE){
		return $longURL;
	}
	
	$ch=curl_init();
	curl_setopt($ch,CURLOPT_URL,"http://dwz.cn/create.php");
	curl_setopt($ch,CURLOPT_POST,true);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
	$data=array('url'=>$longURL);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
	$strRes=curl_exec($ch);
	curl_close($ch);
	$arrResponse=json_decode($strRes,true);
	if($arrResponse['status']!=0)
	{
		dump( iconv('UTF-8','GBK',$arrResponse['err_msg']) );
	}
	
	return $arrResponse['tinyurl'];
}
function getLongURL($shortURL) {
	//如果还在开发模式，不需要短网址服务
	if(DEVELOPMENT_MODE){
		return $shortURL;
	}
	
	$ch=curl_init();
	curl_setopt($ch,CURLOPT_URL,"http://dwz.cn/query.php");
	curl_setopt($ch,CURLOPT_POST,true);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
	$data=array('tinyurl'=>$shortURL);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
	$strRes=curl_exec($ch);
	curl_close($ch);
	$arrResponse=json_decode($strRes,true);
	if($arrResponse['status']!=0)
	{
		dump( iconv('UTF-8','GBK',$arrResponse['err_msg']) );
	}
	
	return $arrResponse['longurl'];
}